<template>
  <div class="tw-form-style">
    <el-form ref="generateForm"
      label-suffix=":"
      :size="config.size"
      :model="models" :rules="rules" :label-position="config.labelPosition" :label-width="config.labelWidth + 'px'">

      <template v-for="item in list">
        <template v-if="item.type == 'grid'">
          <template v-if="item.childType === 'dymFrom'">
            <label class="el-form-item__label tw-formlist-dymlabel" :style="{width: config.labelWidth+'px'}" v-if="item.name">{{item.name}}:</label>
            <div v-for="(col, colIndex) in item.mulforms" :key="colIndex" class="tw-formlist-dymfor" :style="{marginLeft: !item.name ? '0px' : (config.labelWidth+'px')}">
              <template v-for="citem in col.list" >
                <genetate-form-item
                  :key="citem.key"
                  :models.sync="models"
                  :rules="rules"
                  :widget="citem"
                  :config="config"
                  :mulform="item"
                  :colIndex="colIndex"
                  @input-change="onInputChange">
                </genetate-form-item>
              </template>

              <template v-if="colIndex > 0">
                <div class="tw-formlist-delbtn" :class="item.options.disabled ? 'disabled' : ''" v-html="delBtnHtml" @click="delFormItems(item, colIndex)" v-if="item.options.delBtnHtml"></div>
                <i class="tw-formlist-delbtn" :class="(item.options.disabled ? 'disabled' : '') + item.options.delBtnIcon" @click="delFormItems(item, colIndex)" v-else></i>
              </template>
            </div>
            <el-form-item class="tw-formlist-addmul">
              <div v-if="item.options.btnHtml"
               v-html="item.options.btnHtml"
               @click="addFormItems(item)"></div>
              <el-button v-else
               :disabled="item.options.btnDisabled || item.mulforms.length >= item.options.btnLimit || item.options.disabled"
               :size="config.size"
               :type="item.options.btnType"
               @click="addFormItems(item)">
               <i :class="item.options.btnIcon"></i> {{item.options.btnLabel}}
              </el-button>
            </el-form-item>
          </template>

          <template v-else>
            <el-row
              :key="item.key"
              type="flex"
              :class="item.options.customClass || ''"
              :gutter="item.options.gutter ? item.options.gutter : 0"
              :justify="item.options.justify"
              :align="item.options.align"
            >
              <el-col v-for="(col, colIndex) in item.columns" :key="colIndex" :span="col.span">
                <template v-for="citem in col.list" >

                  <genetate-form-item
                    :key="citem.key"
                    :models.sync="models"
                    :rules="rules"
                    :widget="citem"
                    :config="config"
                    @input-change="onInputChange">
                  </genetate-form-item>
                </template>
              </el-col>
            </el-row>
          </template>
        </template>

        <template v-else-if="item.type == 'mulinput'">
          <genetate-mul-form-item
            :key="item.key"
            :models.sync="models"
            :rules="rules"
            :widget="item"
            :config="config"
            @input-change="onInputChange">
          </genetate-mul-form-item>
        </template>

        <template v-else>
          <genetate-form-item
            :key="item.key"
            :models.sync="models"
            :rules="rules"
            :widget="item"
            :config="config"
            @input-change="onInputChange">
          </genetate-form-item>
        </template>

      </template>

      <el-form-item v-if="config.submitBtn" class="tw-formlist-submit">
        <el-button :size="config.size" type="primary" @click="submitForm('generateForm')">提交</el-button>
        <el-button :size="config.size" @click="resetForm('generateForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import GenetateFormItem from './GenerateFormItem'
import GenetateMulFormItem from './GenerateMulFormItem'

export default {
  name: 'tw-generate-form',
  inject: ['_root'],
  components: {
    GenetateFormItem,
    GenetateMulFormItem
  },
  props: ['list', 'config', 'value'],
  data () {
    return {
      models: {},
      defvalue: {},
      rules: {}
    }
  },
  created () {
    this.generateModle(this.list)
  },
  mounted () {
  },
  methods: {
    generateModle (genList) {
      for (let i = 0; i < genList.length; i++) {
        if (genList[i].type === 'grid') {
          if (genList[i].childType === 'dymFrom') {
            // 动态表单制作
            if (this.value && Object.keys(this.value).indexOf(genList[i].model) >= 0) {
              this.models[genList[i].model] = this.value[genList[i].model]
            } else {
              this.models[genList[i].model] = genList[i].options.defaultValue
            }
            if (this.defvalue && this.defvalue[genList[i].model]) {
              this.models[genList[i].model] = this.defvalue[genList[i].model]
            }
            // 动态表单制作

            genList[i].mulforms.forEach(item => {
              this.generateModle(item.list)
            })
          } else {
            genList[i].columns.forEach(item => {
              this.generateModle(item.list)
            })
          }
        } else {
          if (this.value && Object.keys(this.value).indexOf(genList[i].model) >= 0) {
            this.models[genList[i].model] = this.value[genList[i].model]
          } else {
            this.models[genList[i].model] = genList[i].options.defaultValue
          }
          // 动态增加表单时避免清空表单
          if (this.defvalue && this.defvalue[genList[i].model]) {
            this.models[genList[i].model] = this.defvalue[genList[i].model]
          }

          if (this.rules[genList[i].model]) {
            this.rules[genList[i].model] = [...this.rules[genList[i].model], ...genList[i].rules.map(item => {
              if (item.pattern) {
                return {...item, pattern: eval(item.pattern)}
              } else if (item.validator) {
                return {...item, validator: this._root.validFunc(item.validator)}
              } else {
                return {...item}
              }
            })]
          } else {
            this.rules[genList[i].model] = [...genList[i].rules.map(item => {
              if (item.pattern) {
                return {...item, pattern: eval(item.pattern)}
              } else if (item.validator) {
                return {...item, validator: this._root.validFunc(item.validator)}
              } else {
                return {...item}
              }
            })]
          }
        }
      }
    },
    getData () {
      return new Promise((resolve, reject) => {
        this.$refs.generateForm.validate(valid => {
          if (valid) {
            resolve(this.models)
          } else {
            reject(new Error('表单数据校验失败').message)
          }
        })
      })
    },
    reset () {
      this.$refs.generateForm.resetFields()
    },
    onInputChange (value, field) {
      this.defvalue = JSON.parse(JSON.stringify(this.models))
      this.$emit('on-change', field, value, this.models)
    },
    refresh () {

    },
    addFormItems (item) {
      let list = []
      let length = item.mulforms.length
      let mod = {}

      for (let i = 0; i < item.mulforms[0].list.length; i++) {
        let m = item.mulforms[0].list[i].model + length
        list.push({
          ...item.mulforms[0].list[i],
          key: item.mulforms[0].list[i].key + length,
          model: m
        })
        if (item.mulforms[0].list[i].options.autoadd !== undefined && item.mulforms[0].list[i].options.autoadd) {
          let rdata = this._root.getAutoAddValue(item.mulforms[0].list[i].model, length, item.mulforms[0].list[i], this.models[item.model])
          mod[m] = rdata
          this.models[m] = rdata
          this.defvalue[m] = rdata
        } else {
          mod[m] = item.mulforms[0].list[i].options.defaultValue
          this.models[m] = item.mulforms[0].list[i].options.defaultValue
          this.defvalue[m] = item.mulforms[0].list[i].options.defaultValue
        }
      }
      // console.log('mod', mod)
      // console.log('list', list)
      // this.models[item.model].push(mod)
      // this.defvalue[item.model].push(mod)
      this.models[item.model][length] = mod
      this.defvalue[item.model][length] = mod
      item.mulforms.push({list: list})
      // console.log('this.models111', this.models)
      // console.log('item.mulforms111', item.mulforms)
      // console.log('this.defvalue111', this.defvalue)
      // this.$forceUpdate()
      this.onInputChange (this.models[item.model], item.model)
    },
    delFormItems (item, index) {
      window.$ui.confirm('确认删除？','提示',{
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        if (item.mulforms.length > 0) {
          for (let i = index; i < item.mulforms.length; i++) {
            if (i === item.mulforms.length - 1) {
              for (let j = 0; j < item.mulforms[i].list.length; j++) {
                let m = item.mulforms[i].list[j].model
                delete this.models[m]
                delete this.defvalue[m]
              }
            } else {
              for (let j = 0; j < item.mulforms[i].list.length; j++) {
                if (item.mulforms[i].list[j].options.notdel !== undefined && item.mulforms[i].list[j].options.notdel) {

                } else {
                  let m = item.mulforms[i].list[j].model
                  let m1 = item.mulforms[i + 1].list[j].model
                  this.models[item.model][i][m] = this.models[m1]
                  this.models[m] =  this.models[m1]

                  this.defvalue[item.model][i][m] = this.models[m1]
                  this.defvalue[m] =  this.models[m1]
                }
              }
            }
          }

          item.mulforms.pop()
          this.models[item.model].pop()
          this.defvalue[item.model].pop()
          // this.$forceUpdate()
          this.onInputChange (this.models[item.model], item.model)
        }
        window.$ui.msg.success("删除成功")
      })
    },
    submitForm (formName) {
      if (this._root.submitFunc !== '' && typeof this._root.submitFunc === 'function') {
        this._root.submitFunc(formName, this)
      } else {
        window.$ui.confirm('确认提交表单？','提示',{
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$refs[formName].validate((valid) => {
            if (valid) {
              this._root.$emit('input', this.models)
              this._root.$emit('change', this.models)
              window.$ui.msg.success("提交成功")
              // console.log('success submit!!', this.models)
            } else {
              // console.log('error submit!!')
              window.$ui.msg.error("提交失败")
              return false
            }
          })
        })
      }
    },
    resetForm (formName) {
      if (this._root.resetFunc !== '' && typeof this._root.resetFunc === 'function') {
        this._root.resetFunc(formName, this)
      } else {
        window.$ui.confirm('确认重置表单？','提示',{
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$refs[formName].resetFields()
          this._root.$emit('input', this.models)
          this._root.$emit('change', this.models)
          window.$ui.msg.success("重置成功")
        })
        // console.log('success reset!!', this.models)
      }
    }
  },
  watch: {
    list: {
      deep: true,
      handler (val) {
        this.generateModle(val)
      }
    },
    value: {
      deep: true,
      handler (val) {
        let defval = JSON.parse(JSON.stringify(val))
        // this.models = {...this.models, ...val}
        // this.defvalue = {...this.defvalue, ...val}

        // 动态表单重复问题修改
        let isdiff = this._root.diffObject(this.models, val)
        if (!isdiff) {
          let dymforms = []
          this.list.forEach((item, index) => {
            if (item.type === 'grid' && item.childType === 'dymFrom') {
              dymforms.push(item.model)
            }
          })
          if (dymforms.length > 0) {
            this.models = { ...this.models, ...val }
            this.defvalue = { ...this.defvalue, ...val }
            Object.keys(val).forEach((mod) => {
              if (dymforms.includes(mod)) {
                // console.log('dymforms', dymforms)
                // console.log('val.val', val)
                // console.log('this.models[mod]', this.models[mod])
                // console.log('this.defvalue[mod]', this.defvalue[mod])

                this.models[mod] = val[mod]
                this.defvalue[mod] = val[mod]
              }
            })
          } else {
            this.models = { ...this.models, ...val }
            this.defvalue = { ...this.defvalue, ...val }
          }
        }
      }
    }
  }
}
</script>
